一、独热编码(One-Hot Encoding)介绍
One-hot在数字电路中被用来表示一种特殊的位元组合,该字节里,仅容许单一位元为1,其他位元都必须为0。之所以称为one-hot就是因为只能有一个1(hot)。若情况相反,只有一个0,其余为1,则称为one-cold。
在机器学习里,也有one-hot向量(one-hot vector)的概念。在一任意维度的向量中,仅有一个维度的值是1,其余为0。
譬如向量 [ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 ] {\displaystyle {\begin{array}{ll}[0\ 0\ 0\ 0\ 0\ 1\ 0\ 0\ 0\ 0\ 0\ 0\ 0\ 0\ 0]\end{array}}} [0 0 0 0 0 1 0 0 0 0 0 0 0 0 0],即为15维空间中的一组one-hot向量。将分类数据转换成one-hot向量的过程则称one-hot编码(one-hot encoding)。在统计学中,虚拟变数代表了类似的概念。
二、One-Hot编码的应用与代码实现
2.1 自然语言处理(NLP)
在自然语言处理中,若字典或字库里有 N {\displaystyle N} N个字段,则每个字段可以被一个 N {\displaystyle N} N维的one-hot向量代表。
如自然编码为: [ 0 1 ] {\displaystyle {\begin{array}{ll}[0\ 1]\end{array}}} [0 1]
独热编码为: [ 10 01 ] {\displaystyle {\begin{array}{ll}[10\ 01]\end{array}}} [10 01]
譬如若字库里仅有Facebook,Twitter,以及Instagram这三个字段,则他们各自的one-hot向量可以为:
F a c e b o o k = [ 1 0 0 ] T w i t t e r = [ 0 1 0 ] I n s t a g r a m = [ 0 0 1 ] {\displaystyle {\begin{array}{ll}Facebook&=[1\ 0\ 0]\\Twitter&=[0\ 1\ 0]\\Instagram&=[0\ 0\ 1]\end{array}}} FacebookTwitterInstagram=[1 0 0]=[0 1 0]=[0 0 1]
由于电脑无法理解非数字类的数据,One-hot编码可以将分类数据转换成统一的数字格式,方便机器学习算法的处理及计算。而转换成固定维度的向量则方便机器学习算法进行线性代数上的计算。
另外,由于一个one-hot向量中,绝大部分的数字都是0,所以若使用稀疏矩阵的数据结构,则可以节省电脑内存的使用量。
2.2 有限状态机(FSM)
One-hot编码常常被用来表示一个有限状态机的状态。
如果使用二进制(Binary)或格雷码(Gray Code)来代表状态,则需要用到解码器才能得知该码代表的状态。使用one-hot来代表状态的话,则不需要解码器,因为若第 n {\displaystyle n} n个位元为1,就代表机器目前在第 n {\displaystyle n} n个状态。
例如,一个有限状态机是由15个状态构成的环状计数器。使用one-hot编码来实现此状态机的话,可以将15个正反器串联在一起,每个正反器的Q输出接到下一个正反器的D输入,而第一个正反器的D输入则是接到第15个的Q输出,形成一个环状。第一个正反器代表机器的第一个状态,第二个正反器代表第二个状态,依此类推。当机器被归零重设时,第一个正反器的值为1,其余为0。当一个时脉边缘抵达正反器时,会将值1推进到下一个正反器。依照这种方式,值1可一步步推进到第15个正反器,亦即第15个状态,再之后则重新回到第一个状态。
位址解码器可以将二进制或格雷码转换成one-shot表示形式。而优先编码器则作用相反。
2.3 python代码实现
from sklearn import preprocessing
encoder = preprocessing.OneHotEncoder()
#4个特征:
#第一个特征(第一列)为[0,1,3,1]
#第一个特征有三类特征值[0,1,3]:One-Hot Encoding后采用三个编码:[100,010,001]
#同理第二个特征列可将两类特征值[2,3]表示为[10,01]
#第三个特征将4类特征值[1,4,5,7]表示为[1000,0100,0010,0001]
#第四个特征将3类特征值[1,3,5]表示为[100,010,001]
encoder.fit([
[0, 2, 7, 1],
[1, 3, 5, 3],
[3, 3, 1, 5],
[1, 2, 4, 5]
])
encoded_vector = encoder.transform([[3, 2, 7, 5]]).toarray()
print("\n Encoded vector =", encoded_vector)
#[[0. 0. 1. 1. 0. 0. 0. 0. 1. 0. 0. 1.]]
三、One-Hot编码优缺点
3.1 优点
决定状态机目前状态的时间成本低,因为读取一个正反器的时间成本固定。
改变机器的状态所需时间成本也是固定,因为每次只需要改变两个正反器的值。
设计更容易。
容易侦测出非法状态。
可以有效率地使用FPGA的大量正反器。
相较于其他编码,使用one-hot来实现状态机通常可以达到更高的时脉频率。
3.2 缺点
比起其他编码,需要更多的正反器,使得其在PAL装置上不切实际。
会有很多非法状态存在。这是由于 N {\displaystyle N} N个正反器构成的计数器总共有 2 N {\displaystyle 2^{N}} 2N个状态(每个正反器可以是0或1,所以总共 2 N {\displaystyle 2^{N}} 2N种可能状态),但是合法状态却只有 N {\displaystyle N} N个(即同一时间只允许一个正反器是1,其他必须为0),所以总共会有 2 N − N {\displaystyle 2^{N}-N} 2N−N个可能的非法状态。